package com.axzhengxin.platform.sync.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.DSFactory;
import com.axzhengxin.platform.business.domain.BizApplyInfo;
import com.axzhengxin.platform.business.mapper.BizApplyInfoMapper;
import com.axzhengxin.platform.financeProduct.domain.FspFinanceProduct;
import com.axzhengxin.platform.financeProduct.mapper.FspFinanceProductMapper;
import com.axzhengxin.platform.sync.ISyncDataService;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * BizApplyInfoSyncServiceImpl
 * 同步申请信息
 * flag=1的原始数据，同步到biz_apply_info后改为不定向需求，biz_type=UNDIR
 * flag=2的原始数据，依据是否有产品代码来区分DIR和UNDIR，同时造biz_flow_info的数据，流程节点在目标机构的总行管理员
 * flag=4的原始数据，依据是否有产品代码来区分DIR和UNDIR，同时造biz_flow_info的数据，流程节点在业务所属节点，状态为已完成。即syd_apply_info.ghjg以及syd_apply_info.branch
 * flag=6的原始数据，依据是否有产品代码来区分DIR和UNDIR，同时造biz_flow_info的数据，流程节点在业务所属节点，状态为已拒绝。
 *
 * @author jiangnan
 * @date 2021/3/25
 */
@Slf4j
@Service
public class BizApplyInfoSyncServiceImpl implements ISyncDataService {

    static final int ORDER = 0;

    @Autowired
    private DataSource ecscDs;

    @Autowired
    private FspFinanceProductMapper fspFinanceProductMapper;

    @Autowired
    private BizApplyInfoMapper bizApplyInfoMapper;

    private Map<String, FspFinanceProduct> originApplyProductMapper;

    private Map<String, BizApplyInfo> extFieldMapper;

    @SneakyThrows
    @Override
    public void exec() {
        preExec();
        String profile = SpringUtils.getActiveProfile();
        Db.use(DSFactory.get(profile))
                .query("SELECT * FROM SYD_APPLY_INFO t WHERE to_char(t.INPUTDATE, 'yyyymm') IN ('202010', '202011', '202012', '202101', '202102', '202103', '202104') and t.branch != 13 and t.branch is not null")
                .stream()
                .filter(MapUtil::isNotEmpty)
                .filter(entity -> {
                    String reqId = entity.getStr("TRANSSERIALNO");
                    if (StrUtil.isNotBlank(reqId)) {
                        return !reqId.startsWith("aq")
                                && !reqId.startsWith("hs")
                                && !reqId.startsWith("bb");
                    } else {
                        return false;
                    }
                })
                .map(this::convertData)
                .forEach(bizApplyInfoMapper::insertBizApplyInfo);
        originApplyProductMapper.clear();
        extFieldMapper.clear();
    }

    private BizApplyInfo convertData(@NotNull Entity origin) {
        BizApplyInfo bizApplyInfo = new BizApplyInfo();
        bizApplyInfo.setReqId(origin.getStr("SERIALNO"));
        bizApplyInfo.setCustomerId(origin.getStr("CRE_CORNO"));
        bizApplyInfo.setCustomerName(origin.getStr("ENTNAME"));
        // 判断应急贷款标志
        Optional.ofNullable(origin.getStr("URGETN_FLAG"))
                .filter(StrUtil::isNotBlank)
                .filter("1"::equalsIgnoreCase)
                .ifPresent(f -> bizApplyInfo.setApplyType("URGENT"));
        // 填写业务类型
        Optional.ofNullable(origin.getStr("SERIALNO"))
                .filter(originApplyProductMapper::containsKey)
                .map(originApplyProductMapper::get)
                .ifPresent(product -> {
                    bizApplyInfo.setProductId(product.getFprFlowno());
                    bizApplyInfo.setProductName(product.getFprProname());
                    if (StrUtil.isBlank(bizApplyInfo.getApplyType())) {
                        bizApplyInfo.setApplyType("DIR");
                    }
                });
        // 判断经过上述两个步骤后是否已经写入了apply_type，如果还没有则是不定向需求
        if (StrUtil.isBlank(bizApplyInfo.getApplyType())) {
            bizApplyInfo.setApplyType("UNDIR");
        }
        bizApplyInfo.setFinanceAmount(origin.getBigDecimal("DETSUM").divide(new BigDecimal("10000")));
        bizApplyInfo.setFinanceTime(origin.getInt("DETTIME"));
        bizApplyInfo.setPubTime(DateUtil.format(origin.getDate("APPTIME"), "yyyy-MM-dd"));
        bizApplyInfo.setGuaranteeType("2");
        bizApplyInfo.setCreateBy(origin.getStr("RCR_USERNO"));
        bizApplyInfo.setCreateTime(origin.getDate("INPUTDATE"));
        // 填充平台数据的七个扩展字段值
        Optional.ofNullable(extFieldMapper.get(bizApplyInfo.getReqId()))
                .ifPresent(extField -> BeanUtil.copyProperties(extField, bizApplyInfo,
                        CopyOptions.create().ignoreNullValue()));
        return bizApplyInfo;
    }

    @SneakyThrows
    private void preExec() {
        List<Entity> entities = Db.use(ecscDs).find(Arrays.asList("CRE_REQNO",
                "CRE_PROID",
                "LAST_YEAR_SALES",
                "LAST_YEAR_TAX_AMOUNT",
                "CURRENT_BANK_LIABILITIES",
                "bh_bank_sn",
                "sync_status",
                "push_status",
                "sync_channel",
                "business_channel"), Entity.create("fsp_cor_req"));
        loadBasicProductInfo(entities);
        loadExtField(entities);
    }

    /**
     * 从平台库读取业务和产品的关联关系
     *
     * @param entities 平台业务表数据集合
     */
    @SneakyThrows
    private void loadBasicProductInfo(List<Entity> entities) {
        final Map<String, FspFinanceProduct> fspFinanceProductMap = fspFinanceProductMapper
                .selectFspFinanceProductList(new FspFinanceProduct())
                .stream()
                .collect(Collectors.toMap(FspFinanceProduct::getFprFlowno, Function.identity()));
        originApplyProductMapper = entities
                .stream()
                .filter(entity -> StrUtil.isNotBlank(entity.getStr("CRE_PROID")))
                .filter(entity -> fspFinanceProductMap.containsKey(entity.getStr("CRE_PROID")))
                .collect(Collectors.toMap(entity -> entity.getStr("CRE_REQNO"),
                        entity -> fspFinanceProductMap.get(entity.getStr("CRE_PROID"))));

    }


    /**
     * 从平台库读取八个扩展字段与业务编号映射关系
     *
     * @param entities 平台业务表数据集合
     */
    private void loadExtField(List<Entity> entities) {
        extFieldMapper = entities.stream()
                .map(entity -> {
                    BizApplyInfo bai = new BizApplyInfo();
                    bai.setReqId(entity.getStr("CRE_REQNO"));
                    bai.setLastYearSales(entity.getBigDecimal("LAST_YEAR_SALES"));
                    bai.setLastYearTaxAmount(entity.getBigDecimal("LAST_YEAR_TAX_AMOUNT"));
                    bai.setCurrentBankBill(entity.getBigDecimal("CURRENT_BANK_LIABILITIES"));
                    bai.setBohaiBankSn(entity.getStr("BH_BANK_SN"));
                    bai.setUrgentSyncStatus(entity.getStr("SYNC_STATUS"));
                    bai.setPushStatus(entity.getStr("PUSH_STATUS"));
                    bai.setPushChannel(entity.getStr("SYNC_CHANNEL"));
                    return bai;
                })
                .collect(Collectors.toMap(BizApplyInfo::getReqId, Function.identity()));
    }

    @Override
    public int getOrder() {
        return ORDER;
    }

}
